/*
 * Copyright (c) 2006, 2022, webrx.cn All rights reserved.
 *
 */
package cn.webrx.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.EnumSet;
import java.util.List;

/**
 * <p>Project: smvc2022 - WebConfig
 * <p>Powered by webrx On 2022-03-18 16:00:43
 * <p>Created by IntelliJ IDEA
 *
 * @author webrx [webrx@126.com]
 * @version 1.0
 * @since 17
 */
@Configuration
@EnableWebMvc
@ComponentScan("cn.webrx.controller")
@RestController
public class WebConfig implements WebApplicationInitializer, WebMvcConfigurer {
    /**
     * 此方法相当是加载web.xml
     * @param c
     * @throws ServletException
     */
    @Override
    public void onStartup(ServletContext c) throws ServletException {
        var ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(this.getClass());
        ctx.setServletContext(c);

        //配置 DispatcherServlet servlet
        ServletRegistration.Dynamic servlet = c.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);

        //配置 过滤器
        var cc = new CharacterEncodingFilter("utf-8");
        var ff = c.addFilter("cc",cc);
        ff.setInitParameter("forceEncoding", "true"); //此主要解决PrintWriter out 输出编码方式
        ff.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), true, "/usr/*","/show");

    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //-------------配置当前springmvc 项目的消息转换器
        var shmc = new StringHttpMessageConverter();
        shmc.setDefaultCharset(StandardCharsets.UTF_8);
        var list = List.of(MediaType.parseMediaType("text/html;charset=UTF-8"));
        shmc.setSupportedMediaTypes(list);
        converters.add(shmc);

        //如下配置需要引入jackson组件，主要解决json输出，面向接口开发用的
        var m2 = new MappingJackson2HttpMessageConverter();
        //设置日期格式
        ObjectMapper objectMapper = new ObjectMapper();
        //SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd"); //java.util.Date
        SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //java.util.Date
        objectMapper.setDateFormat(smt);
        m2.setObjectMapper(objectMapper);

        //LocalDateTime
        var m = new JavaTimeModule();
        m.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        m.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        //LocalDate
        m.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        m.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        //LocalTime
        m.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        m.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        objectMapper.registerModule(m);
        m2.setObjectMapper(objectMapper);

        //设置中文编码格式
        m2.setSupportedMediaTypes(List.of(MediaType.parseMediaType("application/json;charset=UTF-8")));
        converters.add(m2);

    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //addResourceHandler 虚拟路径   addResourceLocations真实的物理路径
        //registry.addResourceHandler("/b01.jpg").addResourceLocations("/static/imgs/b01.jpg");

        //http://localhost/ss/imgs/b01.jpg 就是访问的 /static/imgs/b01.jpg
        registry.addResourceHandler("/ss/**").addResourceLocations("/static/");
        registry.addResourceHandler("/favicon.ico").addResourceLocations("/favicon.ico");
        registry.addResourceHandler("/**").addResourceLocations("/");
     }

    @RequestMapping
    public String home() {
        return "hello world springmvc - 中文字符串";
    }

    @GetMapping("/show")
    public void show(PrintWriter out) {
        out.print("hello world  汉字");
    }

    @GetMapping("/show2")
    public void show2(HttpServletResponse resp) throws IOException {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<head>");
        out.println("<meta charset=\"utf-8\">");
        out.println("<title>玉灵 QQ:7031633 Email:webrx@126.com</title>");
        out.println("<meta name=\"keywords\" content=\"关键字\">");
        out.println("<meta name=\"description\" content=\"简介\">");
        out.println("</head>");
        out.println("<body>");
        for (int i = 0; i < 3; i++) {
            out.println("<h3>Hello World  中文效果</h3>");
        }
        out.println("</body>");
        out.println("</html>");
        out.flush();
        out.close();
    }
}
